home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Shutdown FX 2.1 / source / sfx control app ƒ / Shell ƒ / graphics.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  17.1 KB  |  535 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        graphics.c
  4.  
  5. Purpose:    This module handles opening/closing/updating all windows:
  6.             this includes manipulating offscreen GWorlds & bitmaps
  7.             for fun and profit.
  8.  
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2 of the License, or
  12. (at your option) any later version.
  13.  
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with this program in a file named "GNU General Public License".
  21. If not, write to the Free Software Foundation, 675 Mass Ave,
  22. Cambridge, MA 02139, USA.
  23.  
  24. \**********************************************************************/
  25.  
  26. #include "graphics.h"
  27. #include "about.h"
  28. #include "about MSG.h"
  29. #include "help.h"
  30. #include "dialogs.h"
  31. #include "error.h"
  32. #include "menus.h"
  33. #include "environment.h"
  34. #include "prefs.h"
  35. #include "util.h"
  36. #include "program globals.h"
  37.  
  38. /* internal global variables for use by graphics.c only */
  39. static    ExtendedWindowDataHandle    gTheWindowData[NUM_WINDOWS];
  40. static    Rect        gBoundsRect[NUM_WINDOWS];        /* rectangle of offscreen bitmap */
  41. static    Rect        gMainScreenBounds;                /* bounds of main monitor */
  42. static    GWorldPtr    gTheGWorld[NUM_WINDOWS];        /* offscreen graphics world */
  43. static    Ptr            gBWBitMap[NUM_WINDOWS];            /* offscreen bitmap for B/W machines */
  44. static    GrafPort    gBWGrafPort[NUM_WINDOWS];        /* offscreen grafport "  "     "     */
  45. static    GrafPtr        gBWGrafPtr[NUM_WINDOWS];        /* offscreen grafptr  "  "     "     */
  46. static    GWorldPtr    currentGWorld;
  47. static    GDHandle    currentGDHandle;
  48.  
  49. Boolean InitTheGraphics(void)
  50. {
  51.     short            i,j;
  52.     
  53.     GetMainScreenBounds();
  54.     
  55.     for (i=0; i<NUM_WINDOWS; i++)
  56.     {
  57.         /* nothing is inited; if there's an error later on, we'll know how much to */
  58.         /* clean up in ShutDownTheGraphics() */
  59.         gTheGWorld[i]=(GWorldPtr)0L;
  60.         gTheWindowData[i]=(ExtendedWindowDataHandle)0L;
  61.     }
  62.     
  63.     for (i=0; i<NUM_WINDOWS; i++)
  64.     {
  65.         gTheWindowData[i]=(ExtendedWindowDataHandle)NewHandle(sizeof(ExtendedWindowDataRec));
  66.         if (gTheWindowData[i]==0L)                            /* return if error */
  67.             return FALSE;
  68.         
  69.         (**(gTheWindowData[i])).offscreenNeedsUpdate=TRUE;    /* offscreen not inited */
  70.         (**(gTheWindowData[i])).theWindowPtr=0L;            /* window ptr not inited */
  71.         (**(gTheWindowData[i])).windowIndex=i;                /* so we can retrieve it O(1) */
  72.         (**(gTheWindowData[i])).windowDepth=
  73.             (**(gTheWindowData[i])).maxDepth=1;                /* init at B/W */
  74.         (**(gTheWindowData[i])).isColor=FALSE;                /* init to grayscale */
  75.         for (j=0; j<MAX_TE_HANDLES; j++)
  76.             (**(gTheWindowData[i])).hTE[j]=0L;
  77.         HLockHi((Handle)gTheWindowData[i]);
  78.     }
  79.     
  80.     /* set window dispatch routines */
  81.     SetIndDispatchProc(kAbout, AboutBoxDispatch);
  82.     SetIndDispatchProc(kHelp, HelpWindowDispatch);
  83.     SetIndDispatchProc(kAboutMSG, AboutMSGBoxDispatch);
  84.     
  85.     /* call window dispatch routines with "startup" message */
  86.     CallIndDispatchProc(kAbout, kStartup, 0L);
  87.     CallIndDispatchProc(kAboutMSG, kStartup, 0L);
  88.     
  89.     return TRUE;
  90. }
  91.  
  92. void OpenTheIndWindow(short index)
  93. {
  94.     WindowPtr        theWindow;
  95.     
  96.     if (!((**gTheWindowData[index]).theWindowPtr))        /* if window exists, we'll just update it (see below) */
  97.     {
  98.         if (CallIndDispatchProc(index, kInitialize, 0L)==kFailure)
  99.         {        /* default is to center window on main screen */
  100.             (**(gTheWindowData[index])).initialTopLeft.h =
  101.                 gMainScreenBounds.left + (((gMainScreenBounds.right -
  102.                 gMainScreenBounds.left) - (**(gTheWindowData[index])).windowWidth) / 2);
  103.             (**(gTheWindowData[index])).initialTopLeft.v =
  104.                 gMainScreenBounds.top + (((gMainScreenBounds.bottom -
  105.                 gMainScreenBounds.top) - (**(gTheWindowData[index])).windowHeight) / 2);
  106.         }
  107.         
  108.         (**(gTheWindowData[index])).windowBounds.left=
  109.             (**(gTheWindowData[index])).initialTopLeft.h;
  110.         
  111.         (**(gTheWindowData[index])).windowBounds.top=
  112.             (**(gTheWindowData[index])).initialTopLeft.v;
  113.             
  114.         if (((**(gTheWindowData[index])).windowType==noGrowDocProc) ||
  115.             ((**(gTheWindowData[index])).windowType==documentProc) ||
  116.             ((**(gTheWindowData[index])).windowType==movableDBoxProc) ||
  117.             ((**(gTheWindowData[index])).windowType==zoomDocProc) ||
  118.             ((**(gTheWindowData[index])).windowType==zoomNoGrow) ||
  119.             ((**(gTheWindowData[index])).windowType==rDocProc))
  120.                 (**(gTheWindowData[index])).windowBounds.top += 9;    /* compensate for title */
  121.         
  122.         /* don't put window over menu bar */
  123.         if ((**(gTheWindowData[index])).windowBounds.top < GetMBarHeight()+1)
  124.             (**(gTheWindowData[index])).windowBounds.top = GetMBarHeight()+1;
  125.         
  126.         (**(gTheWindowData[index])).windowBounds.bottom =
  127.             (**(gTheWindowData[index])).windowBounds.top +
  128.             (**(gTheWindowData[index])).windowHeight;
  129.         
  130.         (**(gTheWindowData[index])).windowBounds.right =
  131.             (**(gTheWindowData[index])).windowBounds.left +
  132.             (**(gTheWindowData[index])).windowWidth;
  133.         
  134.         KillOffscreen(index);        /* kill offscreen bitmaps that are left over */
  135.         
  136.         if (gHasColorQD)
  137.         {
  138.             /* create the color window with our specs, see IM Essentials 4-79ff */
  139.             (**gTheWindowData[index]).theWindowPtr=
  140.                 NewCWindow(0L, &((**(gTheWindowData[index])).windowBounds),
  141.                 (**(gTheWindowData[index])).windowTitle, FALSE,
  142.                 (**(gTheWindowData[index])).windowType, (WindowPtr)-1L,
  143.                 (**(gTheWindowData[index])).hasCloseBox,
  144.                 (unsigned long)gTheWindowData[index]);
  145.         }
  146.         else
  147.         {
  148.             /* create the B/W window with our specs, see IM Essentials 4-82ff */
  149.             (**gTheWindowData[index]).theWindowPtr=
  150.                 NewWindow(0L, &((**(gTheWindowData[index])).windowBounds),
  151.                 (**(gTheWindowData[index])).windowTitle, FALSE,
  152.                 (**(gTheWindowData[index])).windowType, (WindowPtr)-1L,
  153.                 (**(gTheWindowData[index])).hasCloseBox,
  154.                 (unsigned long)gTheWindowData[index]);
  155.         }
  156.     }
  157.     
  158.     if ((theWindow=GetIndWindowGrafPtr(index))!=0L)
  159.     {
  160.         SetPort(theWindow);            /* important! for TE info to stick*/
  161.         /* call window's dispatch routine to alert it that it's open now */
  162.         CallIndDispatchProc(index, kOpen, 0L);
  163.         ShowWindow(theWindow);            /* immediately show this new window */
  164.         SelectWindow(theWindow);        /* immediately select this new window */
  165.     }
  166.     else
  167.     {
  168.         SetErrorParameters("\pOperation: open window", "\p", "\p");
  169.         HandleError(kNoMemory, FALSE, TRUE);            /* if unsuccessful, display error */
  170.     }
  171. }
  172.  
  173. void OpenTheWindow(ExtendedWindowDataHandle theData)
  174. {
  175.     OpenTheIndWindow((**theData).windowIndex);
  176. }
  177.  
  178. void GetMainScreenBounds(void)
  179. {
  180.     gMainScreenBounds = screenBits.bounds;        /* low-mem global */
  181.     gMainScreenBounds.top += GetMBarHeight();    /* don't include menu bar */
  182. }
  183.  
  184. short GetBiggestDeviceDepth(WindowDataHandle theData)
  185. {
  186.     short            index;
  187.     Rect            tempRect;
  188.     long            biggestSize;
  189.     long            tempSize;
  190.     GDHandle        thisHandle, gBiggestDevice;
  191.     
  192.     if (!gHasColorQD)
  193.         return 1;
  194.     
  195.     index=(**theData).windowIndex;
  196.     
  197.     if (!GetIndWindowGrafPtr(index))
  198.         return (**(**GetMainDevice()).gdPMap).pixelSize;
  199.     
  200.     thisHandle = GetDeviceList();
  201.     gBiggestDevice = 0L;
  202.     biggestSize = 0L;
  203.     
  204.     while (thisHandle)
  205.     {
  206.         if (TestDeviceAttribute(thisHandle, screenDevice) &&
  207.             TestDeviceAttribute(thisHandle, screenActive))
  208.         {
  209.             if (SectRect(&(GetIndWindowGrafPtr(index)->portRect), &((**thisHandle).gdRect),
  210.                     &tempRect))
  211.             {
  212.                 if (biggestSize < (tempSize = ((long)(tempRect.bottom - tempRect.top))*
  213.                     ((long)(tempRect.right - tempRect.left))))
  214.                 {
  215.                     biggestSize = tempSize;
  216.                     gBiggestDevice = thisHandle;
  217.                 }
  218.             }
  219.         }
  220.         thisHandle = GetNextDevice(thisHandle);
  221.     }
  222.     
  223.     return (gBiggestDevice) ? (**(**gBiggestDevice).gdPMap).pixelSize : 1;
  224. }
  225.  
  226. short GetWindowDepth(WindowDataHandle theData)
  227. {
  228.     short            index;
  229.     
  230.     index=(**theData).windowIndex;
  231.     /* if Color Quickdraw is not available, the depth must be 1. */
  232.     /* if Color Quickdraw is available and the window exists, return the window's
  233.        GWorld's graphics device's pixel map's pixel depth */
  234.     /* if Color Quickdraw is available and the window does not exist, return the
  235.        pixel depth of the main screen */
  236.     return (gHasColorQD) ? ((GetIndWindowGrafPtr(index)) ?
  237.             (**(**(GetGWorldDevice(gTheGWorld[index]))).gdPMap).pixelSize :
  238.             (**(**GetMainDevice()).gdPMap).pixelSize) : 1;
  239. }
  240.  
  241. Boolean WindowIsColor(WindowDataHandle theData)
  242. {
  243.     short            index;
  244.     
  245.     index=(**theData).windowIndex;
  246.     return (gHasColorQD) ? ((GetWindowDepth(theData)>8) ? TRUE :
  247.         TestDeviceAttribute(GetGWorldDevice(gTheGWorld[index]), gdDevType)) : FALSE;
  248. }
  249.  
  250. void ForceUpdateTheIndWindow(short index)
  251. {
  252.     (**(gTheWindowData[index])).offscreenNeedsUpdate=TRUE;
  253.     UpdateTheWindow(gTheWindowData[index]);
  254. }
  255.  
  256. void UpdateTheWindow(ExtendedWindowDataHandle theData)
  257. {
  258.     short            index;
  259.     long            offRowBytes, sizeOfOff;
  260.     unsigned long    updateResult;
  261.     Boolean            isColor;
  262.     PixMapHandle    thePixMapHandle;
  263.     
  264.     index=(**theData).windowIndex;
  265.     gBoundsRect[index]=GetIndWindowGrafPtr(index)->portRect;
  266.     OffsetRect(&gBoundsRect[index], -gBoundsRect[index].left, -gBoundsRect[index].top);
  267.  
  268.     if (gHasColorQD)    /* w/o Color Quickdraw, GWorlds may not be supported */
  269.     {
  270.         if (gTheGWorld[index]==0L)        /* create new graphics world if none exists */
  271.         {
  272.             /* try to create new graphics world; display error if unsuccessful */
  273.             if (NewGWorld(&gTheGWorld[index],
  274.                 (GetBiggestDeviceDepth(theData)>=(**theData).maxDepth) ?
  275.                 (**theData).maxDepth : 0, &gBoundsRect[index], 0L, 0L, 0)!=0)
  276.             {
  277.                 SetErrorParameters("\pOperation: update window", "\p", "\p");
  278.                 HandleError(kNoMemory, TRUE, TRUE);        /* quits */
  279.             }
  280.             
  281.             (**theData).windowDepth=GetWindowDepth((WindowDataHandle)theData);
  282.             NoPurgePixels(GetGWorldPixMap(gTheGWorld[index]));    /* never purge our pixmap! */
  283.             updateResult=1;
  284.         }
  285.         else updateResult=0;
  286.         
  287.         GetGWorld(¤tGWorld, ¤tGDHandle);    /* get current settings */
  288.         LockPixels(thePixMapHandle=GetGWorldPixMap(gTheGWorld[index]));    /* important!  copybits may move mem */
  289.         /* update offscreen graphics world, compensating for change in pixel depth */
  290.         updateResult|=(unsigned long)UpdateGWorld(&gTheGWorld[index],
  291.             (GetBiggestDeviceDepth(theData)>=(**theData).maxDepth) ? (**theData).maxDepth :
  292.             0, &gBoundsRect[index], 0L, 0L, 0);
  293.         SetGWorld(gTheGWorld[index], 0L);                /* set to our offscreen gworld */
  294.         
  295.         isColor=WindowIsColor(theData);
  296.         if (isColor!=(**theData).isColor)
  297.         {
  298.             (**theData).isColor=isColor;
  299.             updateResult=1;
  300.         }
  301.         
  302.         if ((updateResult!=0L) || ((**theData).windowDepth!=GetWindowDepth(theData)))
  303.         {
  304.             (**theData).windowDepth=GetWindowDepth((WindowDataHandle)theData);    /* save new depth */
  305.             (**theData).offscreenNeedsUpdate=TRUE;                /* we'll need to redraw */
  306.             CallDispatchProc(theData, kChangeDepth, 0L);
  307.         }
  308.     }
  309.     else    /* deal with (guaranteed) B/W bitmaps manually */
  310.     {
  311.         if (gBWGrafPtr[index]==0L)    /* create new offscreen bitmap if none exists */
  312.         {
  313.             gBWGrafPtr[index]=&gBWGrafPort[index];
  314.             OpenPort(gBWGrafPtr[index]);    /* make a new port */
  315.             
  316.             /* calculate the size of the offscreen bitmap from the boundsrect */
  317.             offRowBytes=(((gBoundsRect[index].right-gBoundsRect[index].left)+15)>>4)<<1;
  318.             sizeOfOff=(long)(gBoundsRect[index].bottom-gBoundsRect[index].top)*offRowBytes;
  319.             
  320.             gBWBitMap[index]=NewPtr(sizeOfOff);        /* allocate space for bitmap */
  321.             if (gBWBitMap[index]==0L)                /* abort if unsuccessful */
  322.             {
  323.                 ClosePort(gBWGrafPtr[index]);        /* cleaning up... */
  324.                 gBWGrafPtr[index]=0L;
  325.                 SetErrorParameters("\pOperation: update window", "\p", "\p");
  326.                 HandleError(kNoMemory, TRUE, TRUE);        /* displaying error... */
  327.             }
  328.             
  329.             gBWGrafPort[index].portBits.baseAddr=gBWBitMap[index];    /* --> our bitmap */
  330.             gBWGrafPort[index].portBits.rowBytes=offRowBytes;        /* bitmap size */
  331.             gBWGrafPort[index].portBits.bounds=                        /* bitmap bounds */
  332.                 gBWGrafPort[index].portRect=gBoundsRect[index];
  333.             
  334.             SetPort(gBWGrafPtr[index]);
  335.             (**theData).offscreenNeedsUpdate=TRUE;
  336.         }
  337.         else SetPort(gBWGrafPtr[index]);            /* set port for subsequent drawing */
  338.     }    
  339.     
  340.     if ((**theData).offscreenNeedsUpdate)            /* if we need to redraw */
  341.     {
  342.         (**theData).offscreenNeedsUpdate=FALSE;        /* not anymore */
  343.         /* call window's dispatch and tell it to redraw itself */
  344.         CallDispatchProc(theData, kUpdate, GetWindowDepth((WindowDataHandle)theData));
  345.     }
  346.     
  347.     if (gHasColorQD)
  348.         SetGWorld(currentGWorld, currentGDHandle);    /* restore old settings */
  349.     
  350.     SetPort(GetWindowGrafPtr(theData));
  351.     
  352.     /* copy offscreen bitmap from graphics world or bitmap to onscreen window */
  353.     if (CallDispatchProc(theData, kCopybits, gHasColorQD ? (unsigned long)gTheGWorld[index] :
  354.         (unsigned long)gBWGrafPtr[index])==kFailure)
  355.         CopyBits(gHasColorQD ? &(((GrafPtr)gTheGWorld[index])->portBits) :
  356.                     &(gBWGrafPtr[index]->portBits), &(GetIndWindowGrafPtr(index)->portBits),
  357.                     &gBoundsRect[index], &gBoundsRect[index], 0, 0L);
  358.     
  359.     for (index=0; index<MAX_TE_HANDLES; index++)
  360.     {
  361.         if ((**theData).hTE[index]!=0L)
  362.             TEUpdate(&(GetIndWindowGrafPtr(index)->portRect), (**theData).hTE[index]);
  363.     }
  364.  
  365.     ValidRect(&(GetIndWindowGrafPtr(index)->portRect));        /* so we don't reupdate */
  366.     
  367.     if (gHasColorQD)
  368.         UnlockPixels(thePixMapHandle);    /* remember we locked these? */
  369.     
  370.     KillOffscreen((**theData).windowIndex);
  371. }
  372.  
  373. Boolean CloseTheWindow(ExtendedWindowDataHandle theData)
  374. {
  375.     short            index;
  376.     
  377.     index=(**theData).windowIndex;
  378.     
  379.     /* if the window's dispatch cancels the close, abort */
  380.     if (CallDispatchProc((WindowDataHandle)theData, kClose, 0L)==kCancel)
  381.         return FALSE;
  382.     
  383.     DisposeWindow(GetIndWindowGrafPtr(index));    /* get rid of the actual window in memory */
  384.     (**gTheWindowData[index]).theWindowPtr=0L;    /* so _we_ know the window doesn't exist */
  385.     KillOffscreen(index);                /* kill offscreen bitmaps left over */
  386.     
  387.     /* tell window's dispatch that it's disposed of now */
  388.     CallDispatchProc((WindowDataHandle)theData, kDispose, 0L);
  389.     
  390.     return TRUE;    /* successful close */
  391. }
  392.  
  393. Boolean CloseTheIndWindow(short index)
  394. {
  395.     return CloseTheWindow(gTheWindowData[index]);
  396. }
  397.  
  398. PicHandle DrawThePicture(PicHandle thePict, short whichPict, short x, short y)
  399. /* a standard routine for loading a picture (if necessary) and then drawing it */
  400. {
  401.     Rect            temp;
  402.     
  403.     if (thePict==0L)        /* get it if it doesn't exist */
  404.         thePict=(PicHandle)GetPicture(whichPict);
  405.     
  406.     HLock((Handle)thePict);        /* lock it down for dereferencing to get picture bounds */
  407.     temp.top=y;
  408.     temp.left=x;
  409.     temp.bottom=temp.top+(**thePict).picFrame.bottom-(**thePict).picFrame.top;
  410.     temp.right=temp.left+(**thePict).picFrame.right-(**thePict).picFrame.left;
  411.     DrawPicture(thePict, &temp);    /* draw picture at (x,y) */
  412.     HUnlock((Handle)thePict);        /* unlock for better memory management */
  413.     return thePict;
  414. }
  415.  
  416. PicHandle ReleaseThePict(PicHandle thePict)
  417. {
  418.     if (thePict!=0L)    /* if exists, release it */
  419.         ReleaseResource((Handle)thePict);
  420.     return 0L;
  421. }
  422.  
  423. Boolean SetPortToOffscreen(WindowDataHandle theData)
  424. {
  425.     short            index;
  426.     
  427.     index=(**theData).windowIndex;
  428.     
  429.     if (gHasColorQD)
  430.     {
  431.         if (gTheGWorld[index]==0L)
  432.             return FALSE;
  433.         GetGWorld(¤tGWorld, ¤tGDHandle);    /* get current settings */
  434.         LockPixels(GetGWorldPixMap(gTheGWorld[index]));    /* important!  copybits may move mem */
  435.         SetGWorld(gTheGWorld[index], 0L);
  436.     }
  437.     else
  438.     {
  439.         if (gBWGrafPtr[index]==0L)
  440.             return FALSE;
  441.         SetPort(gBWGrafPtr[index]);
  442.     }
  443.     
  444.     return TRUE;
  445. }
  446.  
  447. void RestorePortToScreen(WindowDataHandle theData)
  448. {
  449.     if (gHasColorQD)
  450.     {
  451.         SetGWorld(currentGWorld, currentGDHandle);    /* restore old settings */
  452.         UnlockPixels(GetGWorldPixMap(gTheGWorld[(**theData).windowIndex]));
  453.     }
  454.     
  455.     SetPort(GetWindowGrafPtr(theData));
  456. }
  457.  
  458. GrafPtr GetOffscreenGrafPtr(WindowDataHandle theData)
  459. {
  460.     if (gHasColorQD)
  461.         return (GrafPtr)gTheGWorld[(**theData).windowIndex];
  462.     else
  463.         return gBWGrafPtr[(**theData).windowIndex];
  464. }
  465.  
  466. GrafPtr GetIndOffscreenGrafPtr(short index)
  467. {
  468.     return GetOffscreenGrafPtr(gTheWindowData[index]);
  469. }
  470.  
  471. GrafPtr GetWindowGrafPtr(WindowDataHandle theData)
  472. {
  473.     return (GrafPtr)((**theData).theWindowPtr);
  474. }
  475.  
  476. GrafPtr GetIndWindowGrafPtr(short index)
  477. {
  478.     return GetWindowGrafPtr(gTheWindowData[index]);
  479. }
  480.  
  481. WindowDataHandle GetIndWindowDataHandle(short index)
  482. {
  483.     return gTheWindowData[index];
  484. }
  485.  
  486. void SetIndDispatchProc(short index, ProcPtr theProc)
  487. {
  488.     (**gTheWindowData[index]).dispatchProc=theProc;
  489. }
  490.  
  491. short CallIndDispatchProc(short index, short theMessage, unsigned long misc)
  492. {
  493.     return ((**(gTheWindowData[index])).dispatchProc)((WindowDataHandle)gTheWindowData[index], theMessage, misc);
  494. }
  495.  
  496. short CallDispatchProc(ExtendedWindowDataHandle theData, short theMessage, unsigned long misc)
  497. {
  498.     return ((**theData).dispatchProc)((WindowDataHandle)theData, theMessage, misc);
  499. }
  500.  
  501. void SetIndWindowTitle(short index, Str255 theTitle)
  502. {
  503.     Mymemcpy((Ptr)((**(gTheWindowData[index])).windowTitle), (Ptr)theTitle, theTitle[0]+1);
  504. }
  505.  
  506. void KillOffscreen(short index)
  507. {
  508.     if (gTheGWorld[index]!=0L)
  509.         DisposeGWorld(gTheGWorld[index]);
  510.     if (gBWGrafPtr[index]!=0L)
  511.         DisposePtr((Ptr)gBWGrafPtr[index]);
  512.     gTheGWorld[index]=0L;
  513.     gBWGrafPtr[index]=0L;
  514.     (**(gTheWindowData[index])).offscreenNeedsUpdate=TRUE;
  515. }
  516.  
  517. void ShutDownTheGraphics(void)
  518. {
  519.     short            i;
  520.     
  521.     /* send shutdown messages to the shell's windows */
  522.     CallIndDispatchProc(kAbout, kShutdown, 0L);
  523.     CallIndDispatchProc(kHelp, kShutdown, 0L);
  524.     CallIndDispatchProc(kAboutMSG, kShutdown, 0L);
  525.     
  526.     for (i=0; i<NUM_WINDOWS; i++)
  527.     {
  528.         KillOffscreen(i);
  529.         if (GetIndWindowGrafPtr(i)!=0L)
  530.             DisposeWindow((**gTheWindowData[i]).theWindowPtr);
  531.         if (gTheWindowData[i]!=0L)
  532.             DisposeHandle((Handle)gTheWindowData[i]);
  533.     }
  534. }
  535.